<template>
  <el-dialog v-el-drag-dialog :title="title" fullscreen :visible.sync="visible" :append-to-body="appendToBody" :before-close="onClose">
    <el-tabs tab-position="top" :value="taskForm.finished === 'true' ? 'approval' : 'detail'">
      <el-tab-pane label="任务审批" name="approval" v-if="taskForm.finished === 'true'">
        <el-card class="box-card m-b-10" shadow="hover" v-if="taskInfo.approval_visible">
          <el-col :span="20" :offset="2">
            <parser :form-conf="taskInfo.formData" ref="parser" @getData="getData" />
          </el-col>
        </el-card>
        <el-card class="box-card m-b-10" shadow="hover">
          <el-row>
            <el-col :span="20" :offset="2">
              <el-form ref="taskForm" :model="taskForm" label-width="80px">
                <el-form-item label="审批结果" prop="comment">
                  <el-radio-group v-model="taskForm.comment">
                    <el-radio label="同意" border>同意</el-radio>
                    <el-radio label="不同意" border>不同意</el-radio>
                  </el-radio-group>
                </el-form-item>
                <el-form-item label="抄送人" prop="copyUsers">
                  <el-tag
                    :key="index"
                    v-for="(item, index) in userData.copyUser"
                    closable
                    :disable-transitions="false"
                    @close="handleCopyUser(item)">
                    {{ item.label }}
                  </el-tag>
                  <el-button class="button-new-tag" type="primary" icon="el-icon-plus" circle @click="handleSelectUser" />
                </el-form-item>
                <el-form-item v-if="userData.nextUser.length > 0" label="指派" prop="nextUsers">
                  <el-transfer
                    v-model="userData.assignee"
                    :props="{
                      key: 'userId',
                      label: 'userName'
                    }"
                    :data="userData.nextUser"
                    :titles="['候选人','审批人']">
                  </el-transfer>
                </el-form-item>
              </el-form>
            </el-col>
          </el-row>
          <el-row :gutter="10" type="flex" justify="center" >
            <el-col :span="1.5">
              <el-button icon="el-icon-circle-check" type="success" v-waves @click="handleComplete">审批</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button icon="el-icon-chat-line-square" type="primary" v-waves @click="handleDelegate">委派</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button icon="el-icon-thumb" type="warning" v-waves @click="handleTransfer">转办</el-button>
            </el-col>
            <el-col :span="1.5" v-permission="['flowable:task:rollback']">
              <el-button icon="el-icon-refresh-left" type="warning" v-waves @click="handleRollback">回退</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button icon="el-icon-circle-close" type="danger" v-waves @click="handleReject">驳回</el-button>
            </el-col>
          </el-row>
        </el-card>
      </el-tab-pane>
      <el-tab-pane label="任务详情" name="detail">
        <div v-if="taskInfo.detail_visible">
          <el-card class="box-card m-b-10" shadow="never" v-for="formInfo in processFormData" :key="formInfo.id">
            <div slot="header" class="clearfix">
              <span>{{ formInfo.title }}</span>
            </div>
            <!--流程处理表单模块-->
            <el-col :span="20" :offset="2">
              <parser :form-conf="formInfo" />
            </el-col>
          </el-card>
        </div>
      </el-tab-pane>
      <el-tab-pane label="流转记录" name="record">
        <el-card class="box-card m-b-10" shadow="never">
          <el-col :span="20" :offset="2">
            <div class="block">
              <el-timeline>
                <el-timeline-item v-for="(item,index) in historyTaskData" :key="index" :icon="setIcon(item.finishTime)" :color="setColor(item.finishTime)">
                  <p style="font-weight: 700">{{ item.taskName }}</p>
                  <el-card :body-style="{ padding: '10px' }" shadow="hover">
                    <el-descriptions v-if="index === 0" class="m-t-10" :labelStyle="{'font-weight': 'bold'}">
                      <el-descriptions-item>
                        <template slot="label"><i class="el-icon-user"></i>申请人</template>
                        {{ item.startUserName || '-'}}
                        <el-tag v-if="item.startDeptName" type="info" size="mini">{{item.startDeptName}}</el-tag>
                      </el-descriptions-item>
                    </el-descriptions>
                    <el-descriptions v-if="index !== 0" class="m-t-10" :labelStyle="{'font-weight': 'bold'}">
                      <el-descriptions-item>
                        <template slot="label"><i class="el-icon-user"></i>办理人</template>
                        {{ item.assigneeName || '-'}}
                        <el-tag v-if="item.deptName" type="info" size="mini">{{item.deptName}}</el-tag>
                      </el-descriptions-item>
                      <el-descriptions-item>
                        <template slot="label"><i class="el-icon-user"></i>待办人</template>
                        {{ item.candidateUsers || '-'}}
                      </el-descriptions-item>
                    </el-descriptions>
                    <el-descriptions class="m-t-10" :labelStyle="{'font-weight': 'bold'}">
                      <el-descriptions-item>
                        <template slot="label"><i class="el-icon-date"></i>接收时间</template>
                        {{ item.createTime || '-'}}
                      </el-descriptions-item>
                      <el-descriptions-item>
                        <template slot="label"><i class="el-icon-date"></i>办结时间</template>
                        {{ item.finishTime || '-' }}
                      </el-descriptions-item>
                      <el-descriptions-item>
                        <template slot="label"><i class="el-icon-time"></i>耗时</template>
                        {{ item.duration || '-'}}
                      </el-descriptions-item>
                    </el-descriptions>
                    <el-descriptions-item>
                      <template slot="label"><i class="el-icon-tickets"></i>处理结果</template>
                      <template v-if="item.commentList && item.commentList.length > 0" v-for="comment in item.commentList">
                        <el-divider content-position="left">
                          <el-tag :type="approveType(comment.type)" size="mini">{{ commentType(comment.type) }}</el-tag>
                          <el-tag type="info" effect="plain" size="mini">{{ comment.time }}</el-tag>
                        </el-divider>
                        <span>{{ comment.fullMessage }}</span>
                      </template>
                    </el-descriptions-item>
                  </el-card>
                </el-timeline-item>
              </el-timeline>
            </div>
          </el-col>
        </el-card>
      </el-tab-pane>
      <el-tab-pane label="流程跟踪" name="track">
        <el-card class="box-card m-b-10" shadow="never">
          <process-viewer :key="`designer-${taskInfo.index}`" :style="'height:' + trackHeight" :xml="taskInfo.xmlData" :finishedInfo="finishedInfo" :allCommentList="historyTaskData" />
        </el-card>
      </el-tab-pane>
    </el-tabs>

    <el-dialog v-el-drag-dialog title="流程回退" :visible.sync="taskInfo.rollback_visible" :append-to-body="true">
      <el-form ref="taskForm" :model="taskForm" label-width="120px">
        <el-card class="m-b-10">
          <el-form-item label="退回节点" prop="targetKey">
            <el-radio-group v-model="taskForm.targetKey">
              <el-radio-button v-for="item in taskInfo.returnTaskList"
                               :key="item.id"
                               :label="item.id"
              >
                {{item.name}}
              </el-radio-button>
            </el-radio-group>
          </el-form-item>
        </el-card>
      </el-form>

      <span slot="footer" class="dialog-footer">
        <el-button type="primary" icon="el-icon-check" @click="handleConfirmRollback">确 定</el-button>
        <el-button icon="el-icon-close" @click="taskInfo.rollback_visible = false">取 消</el-button>
      </span>
    </el-dialog>

    <user-table-dialog v-if="userData.visible" ref="userDialog" :single="false" @confirmDialog="handleConfirmUser" />
  </el-dialog>
</template>

<script>
import {
  processDetailData,
  nextFlowNode,
  flowViewer,
  definitionXml,
  taskDelegate,
  taskTransfer,
  taskComplete,
  taskReject,
  taskRollback,
  taskRollbackList
} from '@/api/tool/workflow'
import Parser from '@/components/Parser'
import ProcessViewer from '@/components/ProcessViewer'
import UserTableDialog from '@/views/system/user/table/selectDialog'

export default {
  name: 'TaskInfoDialog',
  components: {
    Parser,
    ProcessViewer,
    UserTableDialog
  },
  computed: {
    approveType() {
      return val => {
        switch (val) {
          case '1': return 'success'
          case '2': return 'warning'
          case '3': return 'danger'
          case '4': return 'primary'
          case '5': return 'success'
          case '6': return 'danger'
          case '7': return 'info'
        }
      }
    },
    commentType() {
      return val => {
        switch (val) {
          case '1': return '通过'
          case '2': return '退回'
          case '3': return '驳回'
          case '4': return '委派'
          case '5': return '转办'
          case '6': return '终止'
          case '7': return '撤回'
        }
      }
    }
  },
  props: {
    title: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      visible: false,
      appendToBody: true,
      hasLoaded: false,
      trackHeight: document.documentElement.clientHeight - 205 + 'px;',
      taskInfo: {
        index: undefined,
        approval_visible: false,
        formData: {},
        detail_visible: false,
        rollback_visible: false,
        xmlData: ''
      },
      taskForm: {
        procInsId: undefined,
        deployId: undefined,
        taskId: undefined,
        procDefId: undefined,
        finished: false,
        claimUser: undefined,
        copyUsers: undefined,
        variables: {},
        targetKey: undefined,
        comment: '同意'
      },
      userData: {
        visible: false,
        type: '',
        copyUser: [],
        nextUser: [],
        assignee: undefined
      },
      processFormData: [],
      historyTaskData: [],
      finishedInfo: {
        finishedSequenceFlowSet: [],
        finishedTaskSet: [],
        unfinishedTaskSet: [],
        rejectedTaskSet: []
      }
    }
  },
  methods: {
    init(task) {
      this.hasLoaded = false
      this.visible = true
      this.loadTask(task)
    },
    loadTask(task) {
      this.taskForm = this.$api.objectUpdate(this.taskForm, task)
      if (this.taskForm.taskId) {
        // 获取流程变量
        this.getProcessDetailData(this.taskForm.procInsId, this.taskForm.deployId, this.taskForm.taskId)
        // 获取下一步责任人
        this.getNextUser(this.taskForm.taskId)
      }
      // 回显流程记录
      this.$http.all([this.getFlowViewer(this.taskForm.procInsId), this.getModelDetail(this.taskForm.procDefId)]).then(() => {
        this.taskInfo.index = this.taskForm.procInsId
      })
    },
    setIcon(val) {
      if (val) {
        return 'el-icon-check'
      } else {
        return 'el-icon-time'
      }
    },
    setColor(val) {
      if (val) {
        return '#2bc418'
      } else {
        return '#b3bdbb'
      }
    },
    getProcessDetailData(procInsId, deployId, taskId) {
      processDetailData({
        procInsId: procInsId,
        deployId: deployId,
        taskId: taskId
      }).then(response => {
        const detail = response.param
        this.processFormData = detail.processFormList
        this.taskInfo.approval_visible = detail.existTaskForm
        if (this.taskInfo.approval_visible) {
          this.taskInfo.formData = detail.taskFormData
        }

        this.historyTaskData = detail.historyTaskList
        this.taskForm.variables = detail.variables || {}
        this.taskInfo.detail_visible = true
      })
    },
    getNextUser(taskId) {
      nextFlowNode(taskId).then(response => {
        this.userData.nextUser = response.param.userList || []
        // 判断是否代办任务
        if (!this.taskForm.finishTime && this.hasPermission(this.userData.nextUser)) {
          this.taskForm.finished = 'true'
        }
      })
    },
    hasPermission(users) {
      if (users) {
        return users.some(user => user.userId === this.$store.getters.user.userId)
      } else {
        return true
      }
    },
    getFlowViewer(procInsId) {
      return new Promise(resolve => {
        flowViewer(procInsId).then(response => {
          let data = response.param
          if (data) {
            this.finishedInfo.finishedTaskSet = data.finishedTaskSet
            this.finishedInfo.unfinishedTaskSet = data.unfinishedTaskSet
            this.finishedInfo.rejectedTaskSet = data.rejectedTaskSet
            this.finishedInfo.finishedSequenceFlowSet = data.finishedSequenceFlowSet
          }
          resolve()
        })
      })
    },
    getModelDetail(procDefId) {
      return new Promise(resolve => {
        definitionXml(procDefId).then(response => {
          this.taskInfo.xmlData = response.param
          resolve()
        })
      })
    },
    handleSelectUser() {
      this.userData.visible = true
      this.$nextTick(() => {
        this.$refs.userDialog.init()
      })
    },
    handleCopyUser(item) {
      this.userData.copyUser.splice(this.userData.copyUser.indexOf(item), 1)
      if (this.userData.copyUser && this.userData.copyUser.length > 0) {
        this.taskForm.copyUsers = this.userData.copyUser.map(value => value.userId)
      } else {
        this.taskForm.copyUsers = []
      }
    },
    getData(data) {
      this.taskForm.variables = {}
      if (data) {
        const variableData = {}
        data.fields.forEach(item => {
          // 表单值为多个选项时
          if (item.__config__.defaultValue instanceof Array) {
            const array = []
            item.__config__.defaultValue.forEach(val => {
              array.push(val)
            })
            variableData[item.__vModel__] = array
          } else {
            variableData[item.__vModel__] = item.__config__.defaultValue
          }
        })
        this.taskForm.variables = variableData
      }
    },
    validateForm() {
      const taskFormRef = this.$refs.parser
      return new Promise((resolve, reject) => {
        taskFormRef.$refs[taskFormRef.formConfCopy.formRef].validate(valid => {
          valid ? resolve() : reject()
        })
      })
    },
    handleConfirmUser(row) {
      let type = this.userData.type
      if (type === 'copy') {
        this.userData.copyUser = row.map(user => {
          return { id: user.userId, label: user.userName }
        })

        if (this.userData.copyUser && this.userData.copyUser.length > 0) {
          this.taskForm.copyUsers = this.userData.copyUser.map(value => value.userId)
        } else {
          this.taskForm.copyUsers = []
        }
      } else {
        if (!row || row.length <= 0 || row.length > 1) {
          this.$modal.msgWarning('请选择一个责任人')
          return
        }

        this.taskForm.claimUser = row.map(user => user.userId).join('')

        const variables_ = this.$api.deepClone(this.taskForm.variables)
        this.$refs.parser.getData()
        this.taskForm.comment = variables_.comment
        if (!this.taskForm.comment) {
          this.$modal.msgWarning('请输入审批意见')
          return
        }

        const taskFormPromise = this.validateForm()
        this.$http.all(taskFormPromise).then(() => {
          if (type === 'delegate') {
            taskDelegate(this.taskForm).then(response => {
              this.$modal.msgSuccess(response.msg)
              this.$emit('confirm')
              this.onClose()
            })
          } else if (type === 'transfer') {
            taskTransfer(this.taskForm).then(response => {
              this.$modal.msgSuccess(response.msg)
              this.$emit('confirm')
              this.onClose()
            })
          }
        })
      }
    },
    handleComplete() {
      const isExistTaskForm = this.$refs.parser !== undefined
      const taskFormPromise = !isExistTaskForm ? true : this.validateForm()
      const approvalPromise = new Promise((resolve, reject) => {
        this.$refs['taskForm'].validate(valid => {
          valid ? resolve() : reject()
        })
      })

      if (this.userData.assignee && this.userData.assignee.length > 1) {
        this.$modal.msgWarning('请选择一个责任人')
        return
      }

      this.$http.all([taskFormPromise, approvalPromise]).then(() => {
        if (isExistTaskForm) {
          const variables_ = this.$api.deepClone(this.taskForm.variables)
          this.$refs.parser.getData()
          if (!this.taskForm.comment) {
            this.$modal.msgWarning('请输入审批结果')
            return
          }
          if (this.userData.assignee) {
            this.taskForm.variables.assignee = this.userData.assignee
          }
          this.taskForm.variables = this.$api.objectUpdate(this.taskForm.variables, variables_)
        }

        taskComplete(this.taskForm).then(response => {
          this.$modal.msgSuccess(response.msg)
          this.$emit('confirm')
          this.onClose()
        })
      }).catch(() => {})
    },
    handleDelegate() {
      this.$refs['taskForm'].validate(valid => {
        if (valid) {
          this.userData.type = 'delegate'
          this.handleSelectUser()
        }
      })
    },
    handleTransfer(){
      this.$refs['taskForm'].validate(valid => {
        if (valid) {
          this.userData.type = 'transfer'
          this.handleSelectUser()
        }
      })
    },
    handleRollback() {
      this.$refs['taskForm'].validate(valid => {
        if (valid) {
          taskRollbackList(this.taskForm).then(response => {
            this.returnTaskList = response.param
            this.taskInfo.rollback_visible = true
          })
        }
      })
    },
    handleConfirmRollback() {
      this.$refs['taskForm'].validate(valid => {
        if (valid) {
          if (!this.taskForm.targetKey) {
            this.$modal.msgWarning('请选择退回节点！')
          }

          taskRollback(this.taskForm).then(response => {
            this.$modal.msgSuccess(response.msg)
            this.$emit('confirm')
            this.onClose()
          })
        }
      })
    },
    handleReject() {
      this.$refs['taskForm'].validate(valid => {
        if (valid) {
          taskReject({
            taskId: this.taskForm.taskId,
            comment: this.taskForm.comment
          }).then(response => {
            this.$modal.msgSuccess(response.msg)
            this.$emit('confirm')
            this.onClose()
          })
        }
      });
    },
    onClose() {
      this.taskInfo = {
        index: undefined,
        approval_visible: false,
        formData: {},
        detail_visible: false,
        rollback_visible: false,
        xmlData: ''
      }
      this.taskForm = {
        procInsId: undefined,
        deployId: undefined,
        taskId: undefined,
        procDefId: undefined,
        finished: false,
        claimUser: undefined,
        copyUsers: undefined,
        variables: {},
        targetKey: undefined,
        comment: '同意'
      }
      this.userData = {
        visible: false,
        type: '',
        copyUser: [],
        nextUser: []
      }
      this.processFormData = []
      this.historyTaskData = []
      this.finishedInfo = {
        finishedSequenceFlowSet: [],
        finishedTaskSet: [],
        unfinishedTaskSet: [],
        rejectedTaskSet: []
      }
      this.visible = false
    }
  }
}
</script>
